#ifndef VECTOR_DINAMICO_H
#define VECTOR_DINAMICO_H

#include "heap.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>

/* ******************************************************************
 *                DEFINICION DE LOS TIPOS DE DATOS					*
 * *****************************************************************/

typedef struct _vector_dinamico vector_dinamico_t;
typedef void (*vector_destruir_dato_t) (void *);

/* ******************************************************************
 *                    PRIMITIVAS DEL VECTOR							*
 * *****************************************************************/

// Crea un vector de tamaño tam. 'dtr' es una función capaz de destruir
// los elementos del vector. Si se recibe NULL, lógicamente,
// ésta no es aplicada.
// Post: vector es una vector vacío de tamaño tam.
vector_dinamico_t* vector_crear (size_t tam, vector_destruir_dato_t dtr);

// Destruye el vector.
// Pre: el vector fue creado.
// Post: se eliminaron el vector y todos sus elementos.
void vector_destruir (vector_dinamico_t* vector);

// Cambia el tamaño del vector. 'nuevo_tam' debe ser igual o mayor que
// la posición del último elemento existente en el vector.
// Pre: el vector fue creado.
// Post: el vector cambió de tamaño a 'nuevo_tam' y devuelve true
// o el vector queda intacto y devuelve false si no se pudo cambiar el tamaño
// a 'nuevo_tam'.
bool vector_redimensionar(vector_dinamico_t* vector, size_t tam_nuevo);

// Devuelve el dato guardado en la posición 'pos' del vector.
// Devuelve NULL si la posición es inválida.
// Pre: el vector fue creado.
// Post: el dato fue devuelto.
void* vector_obtener (vector_dinamico_t* vector, size_t pos);

// Almacena el valor en la posición 'pos'. De estar ocupada, sobreescribe
// el dato almacenado.
// Pre: el vector fue creado y 'valor' debe ser válido.
// Post: se almacenó el valor en la posición pos. Devuelve false si la posición
// es inválida, y true si se guardó el valor con éxito.
bool vector_guardar (vector_dinamico_t* vector, size_t pos, void* valor);

// Saca el dato hallado en 'pos' y lo devuelve. El vector posee un elemento menos.
// Devuelve NULL si la posición es inválida o está vacía.
// Pre: el vector fue creado.
// Post: el dato fue sacado del vector y devuelto.
void* vector_borrar (vector_dinamico_t* vector, size_t pos);

// Devuelve el tamaño del vector.
// Pre: el vector fue creado.
size_t vector_tamanio (vector_dinamico_t* vector);

// Devuelve la cantidad de elementos que posee el vector.
// Pre: el vector fue creado.
size_t vector_cantidad (vector_dinamico_t* vector);

// Mezcla aleatoriamente los elementos del vector contemplando únicamente
// el rango entre 0 y la cantidad existente.
// Pre: el vector fue creado.
// Post: el vector fue mezclado aleatoriamente.
bool vector_mezclar (vector_dinamico_t* vector);

// Ordena el vector de menor a mayor utilizando heap-sort.
// Pre: el vector fue creado correctamente y es IZQUIERDISTA.
// Post: el vector fue ordenado de menor a mayor.
void vector_ordenar (vector_dinamico_t* vector, cmp_func_t cmp);

#endif // VECTOR_DINAMICO_H
